import { makeAutoObservable } from 'mobx';
import UiState from './UiState';
import PlaybackState from './PlaybackState';
import Logger from './Logs';

export default class CommandTarget {
    is = {};

    _command = undefined;

    constructor() {
        makeAutoObservable(this, {}, { autoBind: true });
    }

    load(command, controls) {
        this._reset();
        this._command = command;
        this.is = controls;
        if (this.is.playToThisPoint || this.is.recordFromHere) this._toggleBreakpoint();
        PlaybackState.toggleIsSilent();
        if (this.is.playToThisPoint) PlaybackState.toggleIsSingleCommandExecutionEnabled();
    }

    doCleanup(opts) {
        this._alert(opts);
        this._reset();
    }

    doPlayToThisPoint() {
        if (this.is.playToThisPoint || this.is.recordFromHere) {
            this._toggleBreakpoint();
            this.is.visited = true;
        }
    }

    async doRecordFromHere(callback) {
        if (!this.is.recordFromHere) return;
        this.doPlayToThisPoint();
        this._prepareTestForRecording();
        if (callback) await callback();
        else await UiState.startRecording();
    }

    _alert(opts = { isTestAborted: false }) {
        if (this._command && !this.is.visited && !opts.isTestAborted) {
            this._logMessage =
                'Unable to play to target command because it was in a control flow branch that was not executed during playback.';
            Logger.warn(this._logMessage);
            if (opts.callback) opts.callback();
        }
    }

    async _prepareTestForRecording() {
        await PlaybackState.playCommand(this._command);
        PlaybackState.stopPlayingGracefully();
        UiState.changeView(PlaybackState.lastSelectedView);
        UiState.selectNextCommand({
            from: this._command,
            isCommandTarget: true,
        });
    }

    _reset() {
        if (this._command && this._command.isBreakpoint) this._toggleBreakpoint();
        this._command = undefined;
        this.is = {};
        this._logMessage = undefined;
        PlaybackState.toggleIsSingleCommandExecutionEnabled();
    }

    _toggleBreakpoint() {
        if (this._command) this._command.toggleBreakpoint();
    }
}
